package one.chchy.demo.sprintsecurity.util;

import org.apache.commons.codec.binary.Hex;
import org.springframework.security.authentication.BadCredentialsException;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;


/**
 * add lyh  2017-11-06
 * @author Administrator
 *
 */
public class EncryptionUtil {
	public static final String VIPARA = "1269571569321021";
	private static final String transformation = "AES/CBC/PKCS5Padding";	
	private static String key = "a7cc6c5acf497f8cec13fd9004fcbadf"; // 默认密钥
	public final static String DATA_ERROR = "Data error!";


//	/**
//	 * 加密
//	 *
//	 * @param byteContent 需要加密的内容
//	 * @param password  加密密码
//	 * @return
//	 */
//	public static byte[] AESEncrypt(byte[] byteContent, String password) {
//        try {
//        	 SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");  //,"Crypto"
//        	 secureRandom.setSeed(password.getBytes());
//        	 //构造密钥生成器，指定为AES算法,不区分大小写
//        	 KeyGenerator kgen = KeyGenerator.getInstance("AES");
//        	 //根据ecnodeRules规则初始化密钥生成器
//        	 kgen.init(128,secureRandom);
//            //产生原始对称密钥
//            SecretKey secretKey = kgen.generateKey();
//            //获得原始对称密钥的字节数组
//            byte[] enCodeFormat = secretKey.getEncoded();
//            //根据字节数组生成AES密钥
//            SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
//            //根据指定算法AES自成密码器
//            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");// 创建密码器
//            //初始化密码器，第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作，第二个参数为使用的KEY
//            cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
//            //获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
//            //byte[] byteContent = content.getBytes("utf-8");
//            //根据密码器的初始化方式--加密：将数据加密
//            byte[] result = cipher.doFinal(byteContent);
//
//           //10.将加密后的数据转换为字符串
//            //这里用Base64Encoder中会找不到包
//            //解决办法：
//            //在项目的Build path中先移除JRE System Library，再添加库JRE System Library，重新编译后就一切正常了。
//           // String AES_encode=new String(new BASE64Encoder().encode(result));
//            return result; // 加密
//        } catch (NoSuchAlgorithmException e) {
//                e.printStackTrace();
//        } catch (NoSuchPaddingException e) {
//                e.printStackTrace();
//        } catch (InvalidKeyException e) {
//                e.printStackTrace();
//        } catch (IllegalBlockSizeException e) {
//                e.printStackTrace();
//        } catch (BadPaddingException e) {
//                e.printStackTrace();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return null;
//	}
//	/**解密
//	 * @param content  待解密内容
//	 * @param password 解密密钥
//	 * @return
//	 */
//	public static byte[] AESDecrypt(byte[] content, String password) {
//	        try {
//
//	        	 SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
//	        	 secureRandom.setSeed(password.getBytes("UTF-8"));
//	        	 //构造密钥生成器，指定为AES算法,不区分大小写
//	        	 KeyGenerator kgen = KeyGenerator.getInstance("AES");
//	        	//根据ecnodeRules规则初始化密钥生成器
//	            //生成一个128位的随机源,根据传入的字节数组
//	        	 kgen.init(128,secureRandom);
//                 //产生原始对称密钥
//                 SecretKey secretKey = kgen.generateKey();
//                 //获得原始对称密钥的字节数组
//                 byte[] enCodeFormat = secretKey.getEncoded();
//                 //根据字节数组生成AES密钥
//                 SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
//                 //根据指定算法AES自成密码器
//                 Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");// 创建密码器   AES/ECB/pkcs5padding
//                 //初始化密码器，第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作，第二个参数为使用的KEY
//                cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
//                //解密
//                byte[] result = cipher.doFinal(content);
//                return result; // 加密
//	        } catch (NoSuchAlgorithmException e) {
//	                e.printStackTrace();
//	        } catch (NoSuchPaddingException e) {
//	                e.printStackTrace();
//	        } catch (InvalidKeyException e) {
//	                e.printStackTrace();
//	        } catch (IllegalBlockSizeException e) {
//	                e.printStackTrace();
//	        } catch (BadPaddingException e) {
//	                e.printStackTrace();
//	        } catch (UnsupportedEncodingException e) {
//				e.printStackTrace();
//			} catch (Exception e) {
//				e.printStackTrace();
//			}
//	        return null;
//	}
//	 /**将二进制转换成16进制
//	  * @param buf
//	  * @return
//	  */
//	 public static String parseByte2HexStr(byte buf[]) {
//	         StringBuffer sb = new StringBuffer();
//	         for (int i = 0; i < buf.length; i++) {
//	                 String hex = Integer.toHexString(buf[i] & 0xFF);
//	                 if (hex.length() == 1) {
//	                         hex = '0' + hex;
//	                 }
//	                 sb.append(hex.toUpperCase());
//	         }
//	         return sb.toString();
//	 }
//
//	 /**将16进制转换为二进制
//	  * @param hexStr
//	  * @return
//	  */
//	 public static byte[] parseHexStr2Byte(String hexStr) {
//	         if (hexStr.length() < 1)
//	                 return null;
//	         byte[] result = new byte[hexStr.length()/2];
//	         for (int i = 0;i< hexStr.length()/2; i++) {
//	                 int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);
//	                 int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);
//	                 result[i] = (byte) (high * 16 + low);
//	         }
//	         return result;
//	 }
//
//
//	 /**
//	 * AES加密数据
//	 * @param data 请求数据
//	 * @param aesKey  AES KEY 值
//	 * @param signfix  固定签名串
//	 * @return Map   aesEncryptByte:请求数据AES加密码后   sign:aesEncryptByte + 签名串进行MD5加密后
//	 */
//	public static Map<String,Object> DataEncrypt(String data,String aesKey,String signfix){
//		String sign = "";
//		Map<String,Object> eMap = new HashMap<String,Object>();
//		try {
//			// 1.压缩处理
//			byte[] compressBytes = GZipUtil.compress(data.getBytes("UTF-8"));
//			// 2.使用AES加密
//			byte[] encodeRequestBytes = EncryptionUtil.AESEncrypt(compressBytes, aesKey);
//			// 3.将加密后的报文与固定签名串进行组合计算签名
//			byte[] signBytes = ArrayUtils.addAll(encodeRequestBytes, signfix.getBytes("utf-8"));
//			sign = Md5.md5(signBytes);
//			eMap.put("aesEncryptByte",encodeRequestBytes); //AES加密后数据
//			eMap.put("sign", sign);
//		} catch (UnsupportedEncodingException e) {
//			e.printStackTrace();
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
//
//		return eMap;
//	}
//
//	    /**
//		 * XOR加密数据
//		 * @param data 请求数据
//		 * @param xorKey  xor KEY 值
//		 * @param signfix  固定签名串
//		 * @return Map   xorEncryptByte:请求数据xor加密码后   sign:xorEncryptByte + 签名串进行MD5加密后
//		 */
//		public static Map<String,Object> DataEncryptXOR(String data,String xorKey,String signfix){
//			String sign = "";
//			Map<String,Object> eMap = new HashMap<String,Object>();
//			try {
//				// 1.压缩处理
//				byte[] compressBytes = GZipUtil.compress(data.getBytes("UTF-8"));
//				// 2.使用xor加密
//				byte[] encodeRequestBytes = xorEncode(compressBytes, xorKey);// 加密处理
//				// 2.1将加密后的报文与固定签名串进行组合计算签名
//				byte[] signBytes = ArrayUtils.addAll(encodeRequestBytes, signfix.getBytes("utf-8"));
//				// 3 MD5加密得出sign
//				sign = Md5.md5(signBytes);
//				eMap.put("xorEncryptByte",encodeRequestBytes); //AES加密后数据
//				eMap.put("sign", sign);
//			} catch (UnsupportedEncodingException e) {
//				e.printStackTrace();
//			} catch (IOException e) {
//				e.printStackTrace();
//			}
//
//			return eMap;
//		}
//		/**
//		 * 加密字符串
//		 * @param pass 需要加密的字符串
//		 * @param key 密钥
//		 * @return
//		 */
//		public static byte[] xorEncode(final byte[] pass, final String key){
//			byte[] keybytes = null;
//			try {
//				keybytes = key.getBytes("utf-8");
//			} catch (UnsupportedEncodingException e) {
//				e.printStackTrace();
//			}
//			byte[] newpass = new byte[pass.length];
//			int n1, n2;
//			if (key.length() == 0)
//				return pass;
//
//			for (n1 = 0, n2 = 0; n1 < pass.length; ++n1) {
//				newpass[n1] = (byte)(pass[n1] ^ keybytes[n2++]);
//				if (n2 >= keybytes.length)
//					n2 = 0;
//			}
//			return newpass;
//		}
//
//	 ////////////////////////////////////////////////////////////////////////////////////////////
//	 /**
//	 * 对接口的数据进行加密
//	 * @param content 明文
//	 * @return String 密文
//	 */
//	public static String encodeContent(String content) {
//		return encodeContent(content, key);
//	}
//	 /**
//	 * 对接口的数据进行加密
//	 * @param content 明文
//	 * @param key 自定义key
//	 * @return String 密文
//	 */
//	public static String encodeContent(String content, String key) {
//		// 获取16位随机数
//		String randomStr = getRandom(16);
//		String contentStr = randomStr + content;
//		// MD5
//		String md5Str = Md5.MD5(contentStr);
//		// 加密
//		return AESUtil.encrypt((contentStr + md5Str), key);
//	}
//
//	/**
//	 * 对接口的数据进行解密
//	 * @param content 密文
//	 * @return String 明文
//	 */
//	public static String decodeContent(String content) {
//		return decodeContent(content, key);
//	}
//
//	/**
//	 * 对接口的数据进行解密
//	 * @param content 密文
//	 * @param key 自定义key
//	 * @return String 明文
//	 */
//	public static String decodeContent(String content, String key) {
//		String result = DATA_ERROR;
//		content = AESUtil.decrypt(content, key);
//		// 解密
//		String contentStr = content.substring(0, content.length() - 32);
//		String md5Str = content.substring(content.length() - 32, content.length());
//		String checkMd5Str = Md5.MD5(contentStr);
//		if (md5Str.equals(checkMd5Str)) {
//			result = contentStr.substring(16, contentStr.length());
//		}
//		return result;
//	}
//	/**
//	 * 生成随机数
//	 * @param length 随机数长度
//	 * @return String 随机数
//	 */
//	public static String getRandom(int length) {// length 小于或等于16
//		return (new Random().nextLong() + "").substring(0, length);
//	}
//
//
//	/**
//	 * 获取文件的MD5码
//	 * @param srcFile 文件
//	 * @return 返回MD5码字符串
//	 * @throws NoSuchAlgorithmException
//	 * @throws IOException
//	 */
//	public static String fileToMD5(File srcFile) throws NoSuchAlgorithmException, IOException {
//		MessageDigest md = MessageDigest.getInstance("MD5");
//
//		InputStream in = new FileInputStream(srcFile);
//		byte[] content = new byte[4096];
//		int numRead = 0;
//
//		while ((numRead = in.read(content)) > 0){
//			md.update(content, 0, numRead);
//		}
//
//		in.close();
//		byte[] digest = md.digest();
//		String result = new String(Hex.encodeHex(digest));
//
//		return result;
//	}
//
//	public static String streamToMD5(InputStream inputStream) throws NoSuchAlgorithmException, IOException {
//		MessageDigest md = MessageDigest.getInstance("MD5");
//
//		byte[] content = new byte[4096];
//		int numRead = 0;
//
//		while ((numRead = inputStream.read(content)) > 0){
//			md.update(content, 0, numRead);
//		}
//
//		byte[] digest = md.digest();
//		String result = new String(Hex.encodeHex(digest));
//
//		return result;
//	}
//
	/**
	 * 获取字符串的MD5值
	 * @param srcStr
	 * @return
	 * @throws NoSuchAlgorithmException 无该算法
	 */
	public static String strToMD5(String srcStr) throws NoSuchAlgorithmException {
		MessageDigest md = MessageDigest.getInstance("MD5");

		byte[] bSrcStr = srcStr.getBytes();
		md.update(bSrcStr);

		byte[] digest = md.digest();
		String result = new String(Hex.encodeHex(digest));

		return result;
	}
//
////    public static void main(String[] argc){
////        String md5 = null;
////        try {
////            md5 = strToMD5("password");
////        } catch (NoSuchAlgorithmException e) {
////            e.printStackTrace();
////        }
////
////        System.out.println(md5);
////    }
//
////    public static void main(String[] argc){
////        CRC32 crc32 = new CRC32();
////        try {
////            crc32.update("123124124325343423098420850238504376".getBytes("utf-8"));
////        } catch (UnsupportedEncodingException e) {
////            e.printStackTrace();
////        }
////        long tmpLong = crc32.getValue();
////
////        byte[] tmpBytes = long2ByteArray(tmpLong);
////
//////        System.out.println(tmpBytes);
////    }
//
//	public static byte[] bytesToMD5(byte[] bytes, int off, int len) throws NoSuchAlgorithmException {
//		MessageDigest md = MessageDigest.getInstance("MD5");
//		byte[] bSrcStr = bytes;
//		md.update(bSrcStr, off, len);
//
//		byte[] digest = md.digest();
//
//		return digest;
//	}
//
//
//	public static byte[] bytesToMD5(byte[] bytes) throws NoSuchAlgorithmException {
////        MessageDigest md = MessageDigest.getInstance("MD5");
////        byte[] bSrcStr = bytes;
////        md.update(bSrcStr);
////
////        byte[] digest = md.digest();
////
////        return digest;
//
//		return EncryptionUtil.bytesToMD5(bytes, 0, bytes.length);
//	}
//
//	/**
//	 * 获取文件的MD5码
//	 * @param inputStream 输入流
//	 * @return 返回MD5码字符串
//	 * @throws NoSuchAlgorithmException
//	 * @throws IOException
//	 */
//	public static byte[] FileToMD5Bytes(InputStream inputStream) throws NoSuchAlgorithmException, IOException {
//		MessageDigest md = MessageDigest.getInstance("MD5");
//
//		InputStream in = inputStream;
//		byte[] content = new byte[4096];
//		int numRead = 0;
//
//		while ((numRead = in.read(content)) > 0){
//			md.update(content, 0, numRead);
//		}
//
//		in.close();
//		byte[] digest = md.digest();
////        String result = new String(Hex.encodeHex(digest));
//
//		return digest;
//	}
//
//
////    public static byte[] bytesToMD516(byte[] bytes) throws NoSuchAlgorithmException {
////
////        byte[] digest = bytesToMD5(bytes);
////        byte[] md516 = new byte[16];
////
////        for (int i = 0; i < 16; ++i){
////            md516[i] = digest[8 + i];
////        }
////
////        return md516;
////    }
//
//	public static String bytesToMD5Str(byte[] bytes) throws NoSuchAlgorithmException {
//		byte[] digest = bytesToMD5(bytes);
//		String result = new String(Hex.encodeHex(digest));
//
//		return result;
//	}

	/**
	 * base64加密
	 * @param originStr 字符串
	 * @return 返回加密结果
	 */
	public static String base64Encryp(String originStr){
		return new BASE64Encoder().encode(originStr.getBytes());
	}

	public static String base64Decode(String baseStr) throws IOException {
		return new String(new BASE64Decoder().decodeBuffer(baseStr), "UTF-8");
	}

	public static String[] decodeHeader(String header) throws IOException {
		String token = EncryptionUtil.base64Decode(header.substring(6).trim());

		int splitIndex = token.indexOf(":");

		if (splitIndex < 0){
			throw new BadCredentialsException("Invalid basic authentication token");
		}

		return new String[]{token.substring(0, splitIndex), token.substring(splitIndex + 1)};
	}

//	/**
//	 * 哈希256加密
//	 * @param data 数据
//	 * @param key key
//	 * @return 返回加密结果
//	 * @throws Exception 返回加密出错异常
//	 */
//	public static String HMACSHA256(byte[] data, byte[] key) throws Exception {
//		try {
//			SecretKeySpec secretKey = new SecretKeySpec(key, "HmacSHA256");
//			Mac mac = null;
//			mac = Mac.getInstance("HmacSHA256");
//			mac.init(secretKey);
//			return GeneraUtil.byte2HexStr(mac.doFinal(data));
//		} catch (NoSuchAlgorithmException e) {
//			e.printStackTrace();
//		} catch (InvalidKeyException e) {
//			e.printStackTrace();
//		}
//
//		throw new Exception("加密出错");
//	}
}
